package com.nft.service.school.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nft.constant.response.ResponseConstants;
import com.nft.po.NftResponse;
import com.nft.service.school.entity.SchoolVisitorEntity;
import com.nft.service.school.entity.SysUserEntity;
import com.nft.service.school.mapper.SchoolVisitorMapper;
import com.nft.service.school.mapper.SysDeptMapper;
import com.nft.service.school.mapper.SysUserMapper;
import com.nft.service.school.req.LoginReq;
import com.nft.service.school.req.SysUserReq;
import com.nft.service.school.resp.LoginResp;
import com.nft.service.school.resp.SysUserResp;
import com.nft.service.school.service.AuthService;
import com.nft.service.school.service.VerifyCodeService;
import com.nft.utils.dateFormat.SimpleDateFormatUtil;
import com.nft.utils.query.QueryUtil;
import com.nft.utils.token.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements AuthService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SchoolVisitorMapper schoolVisitorMapper;

    @Override
    public NftResponse<LoginResp> initAppUser(LoginReq loginReq) {
        //获取到header中的东西
        if(loginReq.getUserName() == null || "".equals(loginReq.getUserName())){
            return new NftResponse<LoginResp>(ResponseConstants.ERROR_CODE,"参数不完整",null);
        }
        if(loginReq.getPhoneCode() == null || "".equals(loginReq.getPhoneCode())){
            return new NftResponse(ResponseConstants.ERROR_CODE,"请输入用户名或者验证码",null);
        }
        Object failCountObject = redisTemplate.opsForValue().get("failCount:"+loginReq.getUserName());
        Integer failCount = 0;
        if(failCountObject != null){
            failCount = Integer.valueOf(failCountObject.toString());
            if(failCount >= 5){
                return new NftResponse<LoginResp>(ResponseConstants.ERROR_CODE,"重试次数达5次，请稍后重试",null);
            }
        }
        Boolean verifyCodeResult = verifyCodeService.verifyCode(loginReq.getUserName(), loginReq.getPhoneCode());
        if(!verifyCodeResult){
            redisTemplate.opsForValue().set("failCount:"+ loginReq.getUserName(), failCount == null ? 1 : (failCount + 1),10*60*1000, TimeUnit.MILLISECONDS);
            return new NftResponse<LoginResp>(ResponseConstants.ERROR_CODE,"验证码不正确",null);
        }
        /*QueryWrapper<SysDeptEntity> wrapperQueryDept = new QueryWrapper<>();
        wrapperQueryDept.ne(QueryUtil.camelToUnderline("parentId"), "0");
        wrapperQueryDept.eq(QueryUtil.camelToUnderline("status"), "0");
        List<SysDeptEntity> deptList = sysDeptMapper.selectList(wrapperQueryDept);
        List<SysDeptResp> deptResult = BeanUtil.copyToList(deptList, SysDeptResp.class);*/
        if(loginReq.getUserId() != null && loginReq.getUserId() > 0){
            Object redisLoginInfoObj = redisTemplate.opsForValue().get("userinfo-app:"+loginReq.getUserId());
            if(redisLoginInfoObj != null){
                LoginResp redisLoginInfo = JSONUtil.toBean(redisLoginInfoObj.toString(), LoginResp.class);
                if(redisLoginInfo.getUserName().equals(loginReq.getUserName())){
                    String token = JwtUtils.token(loginReq.getUserName(),String.valueOf(loginReq.getUserId()));
                    redisLoginInfo.setToken(token);
                    SysUserResp rtn = this.baseMapper.getUserStudent(loginReq.getUserId());
                    if (null!=rtn&&null!=rtn.getUserId()) {
                        redisLoginInfo.setIsTeacher(true);
                    }else {
                        redisLoginInfo.setIsTeacher(false);
                    }
                    redisTemplate.opsForValue().set("userToken-app:"+redisLoginInfo.getUserId(), token,10*24*60*60*1000, TimeUnit.MILLISECONDS);
                    redisTemplate.opsForValue().set("userinfo-app:"+redisLoginInfo.getUserId(), JSONUtil.toJsonStr(redisLoginInfo), 10 * 24 * 60 * 60 * 1000,TimeUnit.MILLISECONDS);
                    redisLoginInfo.setUserName(rtn.getUserName());
                    return new NftResponse(ResponseConstants.SUCCESS_CODE,"登录成功",redisLoginInfo);
                }
            }
        }
        // TODO 验证username + code  redis中没有,从数据库中获取
        SysUserReq sysUserReq = new SysUserReq();
        sysUserReq.setUserName(loginReq.getUserName());
        SysUserResp sysUserResp = this.getUserInfo(sysUserReq);
        if(sysUserResp != null && "1".equals(sysUserResp.getStatus())){
            return new NftResponse(ResponseConstants.ERROR_CODE,"您的账号受限，请联系管理员",null);
        }
        if(sysUserResp == null){
            //用户注册
            NftResponse registerResult = userRegister(sysUserReq);
            if (registerResult.getCode().equals(ResponseConstants.ERROR_CODE)) {
                return new NftResponse(registerResult.getCode(),registerResult.getMsg(),null);
            }
            SysUserEntity userAppEntity = (SysUserEntity) registerResult.getData();
            sysUserResp = BeanUtil.copyProperties(userAppEntity, SysUserResp.class);
        }
        String token = JwtUtils.token(loginReq.getUserName(),String.valueOf(sysUserResp.getId()));
        LoginResp loginResp = BeanUtil.copyProperties(sysUserResp, LoginResp.class);
        loginResp.setPhone(loginReq.getUserName());
        loginResp.setToken(token);
        SysUserResp rtn = this.baseMapper.getUserStudent(loginResp.getUserId());
        if (null!=rtn&&null!=rtn.getUserId()) {
            loginResp.setIsTeacher(true);
        }else {
            loginResp.setIsTeacher(false);
        }
        redisTemplate.opsForValue().set("userToken-app:"+loginResp.getUserId(), token,10*24*60*60*1000, TimeUnit.MILLISECONDS);
        redisTemplate.opsForValue().set("userinfo-app:"+loginResp.getUserId(), JSONUtil.toJsonStr(loginResp), 10 * 24 * 60 * 60 * 1000,TimeUnit.MILLISECONDS);
        loginResp.setUserName(sysUserResp.getUserName());
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"登录成功", loginResp);
    }

    public NftResponse<Boolean> refreshToken(String refreshToken) {
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"刷新token成功",true);
    }

    @Override
    public SysUserResp getUserAppInfo(Integer userId) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("status"), "1");
        wrapper.eq(QueryUtil.camelToUnderline("deleted"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("id"), userId);
        SysUserEntity userAppEntity = this.baseMapper.selectOne(wrapper);
        if(userAppEntity == null){
            return null;
        }
        return BeanUtil.copyProperties(userAppEntity,SysUserResp.class);
    }

    @Override
    public NftResponse<Boolean> logout(Integer userId) {
        SysUserEntity sysUserEntity = this.baseMapper.selectById(userId);
        if(sysUserEntity == null){
            return new NftResponse<>(ResponseConstants.ERROR_CODE,"查无此人",false);
        }
        redisTemplate.delete("userinfo-app:"+userId);
        redisTemplate.delete("userToken-app:"+userId);
        //redisTemplate.delete("verifyCode:"+sysUserEntity.getPhone());
        //redisTemplate.delete("failCount:"+sysUserEntity.getPhone());
        return new NftResponse<>(ResponseConstants.SUCCESS_CODE,"退出登录成功",true);
    }

    public SysUserResp getUserInfo(SysUserReq sysUserReq) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), sysUserReq.getUserName());
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"),"0");
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        List<SysUserEntity> users = this.baseMapper.selectList(wrapper);
        if (null!=users&&users.size()>0) {
            SysUserResp sysUserResp = null;
            for (SysUserEntity sysUserEntity:users) {
                sysUserResp = BeanUtil.copyProperties(sysUserEntity, SysUserResp.class);
                if (null!=sysUserEntity.getStartDate()&&null!=sysUserEntity.getEndDate()) {
                    Date curD = SimpleDateFormatUtil.getNowDate();
                    if (curD.before(sysUserEntity.getStartDate())||curD.after(sysUserEntity.getEndDate())) {
                        SysUserEntity upateUser = new SysUserEntity();
                        upateUser.setUserId(sysUserEntity.getUserId());
                        upateUser.setStatus("1");
                        sysUserMapper.updateById(upateUser);
                        sysUserResp.setStatus("1");
                    }
                }
                SysUserResp rtn = this.baseMapper.getUserStudent(sysUserEntity.getUserId());
                if (null!=rtn&&null!=rtn.getUserId()) {
                    sysUserResp.setIsTeacher(true);
                }else {
                    sysUserResp.setIsTeacher(false);
                }
            }
            return sysUserResp;
        }else {
            return null;
        }
    }

    /**
     * 用户注册
     * @param sysUserReq
     * @return
     */
    public NftResponse userRegister(SysUserReq sysUserReq) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), sysUserReq.getUserName());
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"),"0");
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        Long userCount = this.baseMapper.selectCount(wrapper);
        if(userCount > 0) {
            return new NftResponse(ResponseConstants.ERROR_CODE,"您的手机号已经注册过了",null);
        }
        //用户注册数据拼装
        long count=this.baseMapper.selectCount(null);
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setPhonenumber(sysUserReq.getUserName());
        sysUserEntity.setUserName("学生"+(count+1));
        sysUserEntity.setCreateTime(SimpleDateFormatUtil.getNowDate());

        SchoolVisitorEntity schoolVisitorEntity = new SchoolVisitorEntity();
        schoolVisitorEntity.setName("未名");
        schoolVisitorEntity.setPhone(sysUserReq.getUserName());
        schoolVisitorEntity.setCreateTime(SimpleDateFormatUtil.getNowDate());
        schoolVisitorMapper.insert(schoolVisitorEntity);
        //新增用户数据
        Integer result = this.baseMapper.insert(sysUserEntity);
        if(result <= 0){
            return new NftResponse(ResponseConstants.ERROR_CODE,"注册失败",null);
        }
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"注册成功", sysUserEntity);
    }

    public NftResponse userMinRegister(SysUserReq sysUserReq) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), sysUserReq.getUserName());
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"),"0");
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        Long userCount = this.baseMapper.selectCount(wrapper);
        if(userCount > 0) {
            return new NftResponse(ResponseConstants.ERROR_CODE,"您的手机号已经注册过了",null);
        }
        //用户注册数据拼装
        long count=this.baseMapper.selectCount(null);
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setPhonenumber(sysUserReq.getUserName());
        sysUserEntity.setUserName("获取姓名");
        sysUserEntity.setCreateTime(SimpleDateFormatUtil.getNowDate());
        Integer result = this.baseMapper.insert(sysUserEntity);
        if(result <= 0){
            return new NftResponse(ResponseConstants.ERROR_CODE,"注册失败",null);
        }
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"注册成功", sysUserEntity);
    }
}
